package oauth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import oauth.security.DomainUserDetailsService;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter
{
	@Autowired
	private AuthenticationManager authenticationManager;

	@Autowired
	private RedisConnectionFactory connectionFactory;

	@Bean
	public UserDetailsService userDetailsService()
	{
		return new DomainUserDetailsService();
	}

	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints)
		throws Exception
	{
		endpoints
			.authenticationManager(authenticationManager)
			.userDetailsService(userDetailsService())//若无，refresh_token会有UserDetailsService is required错误
			.tokenStore(tokenStore());
	}

	@Bean
	public MyRedisTokenStore tokenStore()
	{
		return new MyRedisTokenStore(connectionFactory);
	}

	@Override
	public void configure(AuthorizationServerSecurityConfigurer security)
		throws Exception
	{
		security
			.tokenKeyAccess("permitAll()")
			.checkTokenAccess("isAuthenticated()");
	}

	@Override
	public void configure(ClientDetailsServiceConfigurer clients)
		throws Exception
	{
		clients.inMemory()
			.withClient("android")
			.scopes("xx")
			.secret("android")
			.authorizedGrantTypes("password", "authorization_code", "refresh_token")
			.and()
			.withClient("webapp")
			.scopes("xx")
			.authorizedGrantTypes("implicit");
	}
}
